Los Angeles Crime Dashboard

Summary

This page analyzes crime patterns in Los Angeles by looking at trends over time, the most common crime types, crime hotspots by ZIP code, and victim age characteristics. These visualizations help identify when crimes peak, which offenses are most frequent, and how different groups of victims are affected.

LA Crime Map (Basic Marker Map)

Code
import folium
from folium.plugins import MarkerCluster
import pandas as pd

df = pd.read_csv("data/los_angeles.csv")

la_map = folium.Map(location=[34.0522, -118.2437], zoom_start=10)
marker_cluster = MarkerCluster().add_to(la_map)

df_sample = df.sample(n=5000, random_state=42)

for _, row in df_sample.iterrows():
    folium.CircleMarker(
        location=[row["latitude"], row["longitude"]],
        radius=3,
        color="red",
        fill=True,
        fill_opacity=0.6
    ).add_to(marker_cluster)

la_map
Make this Notebook Trusted to load map: File -> Trust Notebook

Prepare Data

Code
import pandas as pd

df = pd.read_csv("data/los_angeles.csv")

df["incident_date"] = pd.to_datetime(df["incident_date"], errors="coerce")
df["year"] = df["incident_date"].dt.year
df["month"] = df["incident_date"].dt.month
df["month_name"] = df["incident_date"].dt.strftime("%b")

df = df.dropna(subset=["year", "month"])

monthly_total = (
    df.groupby(["year", "month", "month_name"])
    .size()
    .reset_index(name="crime_count")
)

Neighborhood Analysis

Code
import plotly.express as px
import pandas as pd

df = pd.read_csv("data/los_angeles.csv")

top_neighborhoods = df["area_name"].value_counts().head(10)

fig = px.bar(
    x=top_neighborhoods.index,
    y=top_neighborhoods.values,
    labels={"x": "Neighborhood", "y": "Incidents"},
    title="Top 10 Neighborhoods by Number of Crimes – Los Angeles",
    text=top_neighborhoods.values
)

fig.update_traces(marker_color="tomato", textposition="outside")
fig.update_layout(
    xaxis_tickangle=35,
    template="simple_white",
    height=500
)

fig.show()

Crime Hotspots — Top ZIP Codes

Code
df["zip_code"] = df["zip_code"].astype(str).str.replace(".0", "", regex=False)

zip_counts = (
    df.groupby("zip_code")
      .size()
      .reset_index(name="crime_count")
      .sort_values("crime_count", ascending=False)
)

top_zip = zip_counts.head(10)

import plotly.express as px

fig = px.bar(
    top_zip.sort_values("crime_count"),
    x="crime_count",
    y="zip_code",
    orientation="h",
    title="Top 10 ZIP Codes by Total Crime",
    labels={"zip_code": "ZIP Code", "crime_count": "Total Crimes"},
    template="plotly_white"
)

fig

Victim Age Distribution

Code
import plotly.express as px

# 1. Clean age data
df_age_clean = df[(df["victim_age"] >= 0) & (df["victim_age"] <= 120)]

# 2. Select TOP 5 crime categories
top5_age = (
    df_age_clean["crime_description"]
      .value_counts()
      .head(5)
      .index
)

df_top5 = df_age_clean[df_age_clean["crime_description"].isin(top5_age)]

# 3. Build a clean histogram
fig = px.histogram(
    df_top5,
    x="victim_age",
    color="crime_description",
    nbins=40,
    barmode="overlay",
    opacity=0.6,
    title="Victim Age Distribution (Top 5 Crime Categories)",
    template="plotly_white"
)

fig.update_layout(
    legend_title_text="Crime Category",
    bargap=0.05
)

fig

Victim Age Groups

Code
import pandas as pd
import plotly.express as px

# --- Clean age data ---
df_age_clean = df[(df["victim_age"] >= 0) & (df["victim_age"] <= 120)].copy()

df_age_clean.loc[:, "age_group"] = pd.cut(
    df_age_clean["victim_age"],
    bins=[0, 18, 30, 45, 60, 120],
    labels=["0–18", "19–30", "31–45", "46–60", "60+"]
)

# --- Step 1: Select Top 10 crimes by total count ---
top10_crimes = (
    df_age_clean["crime_description"]
      .value_counts()
      .head(10)
      .index
)

df_top10 = df_age_clean[df_age_clean["crime_description"].isin(top10_crimes)]

# --- Step 2: Group for plotting ---
age_group_df = (
    df_top10
        .dropna(subset=["age_group"])
        .groupby(["crime_description", "age_group"], observed=True)
        .size()
        .reset_index(name="count")
)

# --- Step 3: Plot ---
fig = px.bar(
    age_group_df,
    x="crime_description",
    y="count",
    color="age_group",
    barmode="stack",
    title="Victim Age Groups (Top 10 Crimes)",
    template="plotly_white"
)

# Make x labels readable
fig.update_layout(
    xaxis_tickangle=-45,
    legend_title_text="Age Group"
)

fig